/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * Main.java
 *
 * Created on 1 Jan, 2010, 11:09:42 AM
 */
package jaspect;

import jaspect.control.ConfigurationBuilder;

import jaspect.model.AJCompiler;
import jaspect.model.AspectConfiguration;
import jaspect.model.AspectMethod;
import jaspect.model.JAspectProject;
import jaspect.model.Compiler;
import jaspect.model.MakeFile;
import jaspect.model.Utils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultListModel;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import jsyntaxpane.DefaultSyntaxKit;
import myaspects.DB;

/**
 *
 * @author Arjun
 */
public class Main extends javax.swing.JFrame {
/** projectFolder is the directory where the currently working project of the user is stored
 */
    public static String projectFolder = null;
    static JAspectProject project = new JAspectProject();

    /**
     * @return tm  the tree model
     */
    public static DefaultTreeModel getTm() {
        return tm;
    }

    /**
     * @param aTm the tm to set
     */
    public static void setTm(DefaultTreeModel aTm) {
        tm = aTm;
    }
    Map<String, ConfigurationBuilder> configs = new HashMap<String, ConfigurationBuilder>();
    private JFileChooser fchoo;
    private JFileChooser fchos;
    private String javaFile, outputJavaFile;
    private List<String> ajxmlFile = new ArrayList<String>();
    DefaultListModel modAspectsList = new DefaultListModel();
    private static DefaultTreeModel tm;

    /** Creates new form Main.
     * Initializes the syntax kit.
     * Initializes the projectTree
     */
    public Main() {
        initComponents();
        DefaultSyntaxKit.initKit();

        DefaultMutableTreeNode root = new DefaultMutableTreeNode(null);
        tm = (DefaultTreeModel) projectTree.getModel();
        tm.setRoot(root);

        lstAspects.setModel(modAspectsList);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        pmAspectContext = new javax.swing.JPopupMenu();
        miInject = new javax.swing.JMenuItem();
        miEditAspect = new javax.swing.JMenuItem();
        miCreateAspectClass = new javax.swing.JMenuItem();
        pmSrcPop = new javax.swing.JPopupMenu();
        miNewFile = new javax.swing.JMenuItem();
        jToolBar1 = new javax.swing.JToolBar();
        bAspect = new javax.swing.JButton();
        bTranslate = new javax.swing.JButton();
        bJavaCompile = new javax.swing.JButton();
        bRun = new javax.swing.JButton();
        bRunProject = new javax.swing.JButton();
        jButton1 = new javax.swing.JButton();
        jSplitPane1 = new javax.swing.JSplitPane();
        jScrollPane2 = new javax.swing.JScrollPane();
        lstAspects = new javax.swing.JList();
        jScrollPane1 = new javax.swing.JScrollPane();
        editorJava = new javax.swing.JEditorPane();
        jScrollPane3 = new javax.swing.JScrollPane();
        compileComments = new javax.swing.JTextPane();
        treePane = new javax.swing.JScrollPane();
        projectTree = new javax.swing.JTree();
        jMenuBar1 = new javax.swing.JMenuBar();
        mFile = new javax.swing.JMenu();
        miNewProject = new javax.swing.JMenuItem();
        miOpen = new javax.swing.JMenuItem();
        miSave = new javax.swing.JMenuItem();
        miSaveAs = new javax.swing.JMenuItem();
        mEdit = new javax.swing.JMenu();
        jMenuItem3 = new javax.swing.JMenuItem();
        jMenuItem4 = new javax.swing.JMenuItem();
        jMenuItem5 = new javax.swing.JMenuItem();
        jMenuItem6 = new javax.swing.JMenuItem();

        miInject.setText("Inject");
        miInject.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miInjectActionPerformed(evt);
            }
        });
        pmAspectContext.add(miInject);

        miEditAspect.setText("Edit aspect");
        miEditAspect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miEditAspectActionPerformed(evt);
            }
        });
        pmAspectContext.add(miEditAspect);

        miCreateAspectClass.setText("jMenuItem1");
        miCreateAspectClass.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miCreateAspectClassActionPerformed(evt);
            }
        });
        pmAspectContext.add(miCreateAspectClass);

        miNewFile.setText("jMenuItem1");
        miNewFile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miNewFileActionPerformed(evt);
            }
        });
        pmSrcPop.add(miNewFile);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jToolBar1.setRollover(true);

        bAspect.setText("Define Aspect");
        bAspect.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bAspectActionPerformed(evt);
            }
        });
        jToolBar1.add(bAspect);

        bTranslate.setText("Translate");
        bTranslate.setFocusable(false);
        bTranslate.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        bTranslate.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        bTranslate.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bTranslateActionPerformed(evt);
            }
        });
        jToolBar1.add(bTranslate);

        bJavaCompile.setText(" Compile");
        bJavaCompile.setFocusable(false);
        bJavaCompile.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        bJavaCompile.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        bJavaCompile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bJavaCompileActionPerformed(evt);
            }
        });
        jToolBar1.add(bJavaCompile);

        bRun.setText("Run");
        bRun.setFocusable(false);
        bRun.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        bRun.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        bRun.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bRunActionPerformed(evt);
            }
        });
        jToolBar1.add(bRun);

        bRunProject.setText("Run Project");
        bRunProject.setFocusable(false);
        bRunProject.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        bRunProject.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        bRunProject.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bRunProjectActionPerformed(evt);
            }
        });
        jToolBar1.add(bRunProject);

        jButton1.setText("Connect");
        jButton1.setFocusable(false);
        jButton1.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton1.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
        jToolBar1.add(jButton1);

        jSplitPane1.setDividerLocation(450);
        jSplitPane1.setDividerSize(3);
        jSplitPane1.setAutoscrolls(true);
        jSplitPane1.setMinimumSize(new java.awt.Dimension(43, 20));
        jSplitPane1.setOneTouchExpandable(true);
        jSplitPane1.setPreferredSize(new java.awt.Dimension(811, 112));

        lstAspects.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        lstAspects.setPreferredSize(new java.awt.Dimension(100, 80));
        lstAspects.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                lstAspectsMouseClicked(evt);
            }
        });
        jScrollPane2.setViewportView(lstAspects);

        jSplitPane1.setRightComponent(jScrollPane2);

        editorJava.setMinimumSize(new java.awt.Dimension(700, 20));
        editorJava.setPreferredSize(new java.awt.Dimension(800, 20));
        jScrollPane1.setViewportView(editorJava);

        jSplitPane1.setLeftComponent(jScrollPane1);

        jScrollPane3.setPreferredSize(new java.awt.Dimension(80, 150));

        compileComments.setEditable(false);
        jScrollPane3.setViewportView(compileComments);

        projectTree.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                projectTreeMouseClicked(evt);
            }
        });
        treePane.setViewportView(projectTree);

        mFile.setText("File");
        mFile.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mFileActionPerformed(evt);
            }
        });

        miNewProject.setText("New Project");
        miNewProject.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miNewProjectActionPerformed(evt);
            }
        });
        mFile.add(miNewProject);

        miOpen.setMnemonic('O');
        miOpen.setText("Open Project");
        miOpen.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miOpenActionPerformed(evt);
            }
        });
        mFile.add(miOpen);

        miSave.setText("Save");
        miSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miSaveActionPerformed(evt);
            }
        });
        mFile.add(miSave);

        miSaveAs.setText("Save as");
        miSaveAs.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                miSaveAsActionPerformed(evt);
            }
        });
        mFile.add(miSaveAs);

        jMenuBar1.add(mFile);

        mEdit.setText("Edit");

        jMenuItem3.setText("Copy");
        jMenuItem3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem3ActionPerformed(evt);
            }
        });
        mEdit.add(jMenuItem3);

        jMenuItem4.setText("Cut");
        mEdit.add(jMenuItem4);

        jMenuItem5.setText("Paste");
        mEdit.add(jMenuItem5);

        jMenuItem6.setText("Delete");
        mEdit.add(jMenuItem6);

        jMenuBar1.add(mEdit);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 687, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGroup(layout.createSequentialGroup()
                .addGap(6, 6, 6)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(jScrollPane3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
                        .addComponent(treePane, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jSplitPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 565, javax.swing.GroupLayout.PREFERRED_SIZE))))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(treePane, 0, 0, Short.MAX_VALUE)
                    .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 192, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 142, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-703)/2, (screenSize.height-424)/2, 703, 424);
    }// </editor-fold>//GEN-END:initComponents


       
    /** This method is called when the user click on the menu item labelled 'Open Project'.
 * This method opens a FileChooser for selecting a project directory identified by
 * the presence of a .pro file.
 * This method also sets the project directory and also uses the MekeFile class
 * to display the files in the opened project in a tree format
 * @param evt
 */
    private void miOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miOpenActionPerformed
       File directory = null;
        JFileChooser chooser = new JFileChooser();
        while (true) {

            // chooser = new JFileChooser();
            chooser.setCurrentDirectory(directory);
            chooser.setDialogTitle("Project Directory");
            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            //
            // disable the "All files" option.
            //
            chooser.setAcceptAllFileFilterUsed(false);

            if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
                File dir = chooser.getSelectedFile();
                int i;
                String[] children = dir.list();
                if (children == null) { // Either dir does not exist or is not a directory
                } else {
                    for (i = 0; i < children.length; i++) { // Get filename of file or directory
                        String fileName = children[i];

                        if (fileName.equals("project.pro")) {
                            break;

                        }
                    }
                    if (i != children.length) {
                        break;

                    }
                    directory = chooser.getSelectedFile();

                }

            }
        }
        try {
            MakeFile.newProject(chooser.getSelectedFile().getAbsolutePath());
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            MakeFile.openMake(chooser.getSelectedFile().getAbsolutePath());
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }

        projectFolder = chooser.getSelectedFile().getAbsolutePath();


     
        
   
    }//GEN-LAST:event_miOpenActionPerformed

    /** This method is used to read the contents of a java file and display it
     * on the editor pane.
     * @param f
     * @throws FileNotFoundException
     * @throws IOException
     */
    public void openJava(File f) throws FileNotFoundException, IOException {

        BufferedReader br = new BufferedReader(new FileReader(f.getAbsolutePath()));

        StringBuffer sb = new StringBuffer();
        this.setJavaFile(f.getName());

        while (br.ready()) {

            sb.append(br.readLine());
            sb.append("\n");

        }

        editorJava.setContentType("text/java");
        editorJava.setText(sb.toString());
        setOutputJavaFile(f.getAbsolutePath().substring(f.getAbsolutePath().lastIndexOf("\\") + 1, f.getAbsolutePath().length()));

    }
/**This method returns the current working java file
 * @return javaFile
 */
    public String getJavaFile() {
        return javaFile;
    }
/**This method sets the current working java file
 * @param javaFile
 */
    public void setJavaFile(String javaFile) {
        this.javaFile = javaFile;
    }
    /** This method is called when the user clicks on the list of Aspects.
     * If an Aspect is selected and right clicked, then a popup menu is opened
     * showing the menus for edit, inject and create
     * @param evt
     */
    private void lstAspectsMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_lstAspectsMouseClicked
        // TODO add your handling code here:
        if ((java.awt.event.MouseEvent.BUTTON3 == evt.getButton()) && (lstAspects.getSelectedIndex() >= 0)) {

            AspectConfiguration ac = (AspectConfiguration) lstAspects.getSelectedValue();

            if (ac != null) {

                miEditAspect.setText("Edit '" + ac.getName() + "' aspect");
                miInject.setText("Inject '" + ac.getName() + "'");
                miCreateAspectClass.setText("Create '" + ac.getName() + "' aspect class");
                pmAspectContext.show(lstAspects, evt.getX(), evt.getY());
            }
        }
    }//GEN-LAST:event_lstAspectsMouseClicked
/** This method is called when the inject item in the Aspect popup menu is clicked
 * It checks the intercept mode of the Aspect- whether member or method
 * and correspondingly opens the dialog window
 * @param evt
 */
    private void miInjectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miInjectActionPerformed
        // TODO add your handling code here:
        AspectConfiguration ac = (AspectConfiguration) lstAspects.getSelectedValue();

        if (ac != null) {
            if (AspectConfiguration.InterceptMode.member.equals(ac.getMode())) {

                InjectMemberJDialog d = new InjectMemberJDialog(this, true);
                d.displayMethods(ac);
                d.setParent(this);
                d.setAspc(ac);
                d.setVisible(true);

            }
            if (AspectConfiguration.InterceptMode.method.equals(ac.getMode())) {

                InjectMethodJDialog d = new InjectMethodJDialog(this, true);
                d.listMethods(ac.getMethods());
                d.setParent(this);
                d.setAspc(ac);
                d.setVisible(true);


            }

        }
    }//GEN-LAST:event_miInjectActionPerformed
/** This method is called when the edit item in the Aspect popup menu is clicked
 * This method initializes an instane of AspectDefDlg to display the details
 * of the selected aspect for editing.
 * @param evt
 */
    private void miEditAspectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miEditAspectActionPerformed
        // TODO add your handling code here:
        AspectConfiguration ac = (AspectConfiguration) lstAspects.getSelectedValue();

        if (ac != null) {

            AspectDefDlg d = new AspectDefDlg(this, true);
            d.setConfig(ac);
            d.setVisible(true);
        }
    }//GEN-LAST:event_miEditAspectActionPerformed

    /** This method is called when the 'Define Aspect' button is clicked.
     * It creates an instance of AspectDefDlg for the user to define a new Aspect.
     * @param evt
     */
    private void bAspectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bAspectActionPerformed
        // TODO add your handling code here:
        AspectDefDlg d = new AspectDefDlg(this, true);
        d.setParentF(this);
        d.setVisible(true);


    }//GEN-LAST:event_bAspectActionPerformed

    private void mFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mFileActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_mFileActionPerformed
/** This method is called when the 'Translate' button is clicked.
 * It calls the AJCompiler class to translate the source files into pure jave files.
 * It also makes sure that the files are saved before compilation.
 * @param evt
 */
    private void bTranslateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bTranslateActionPerformed


        String[] args = new String[4];
        if (projectFolder == null) {
            miSaveAsActionPerformed(evt);
        }

        args[0] = projectFolder + "\\" + this.getJavaFile();

        Iterator t = this.ajxmlFile.iterator();
        int i = 0;
        while (t.hasNext()) {
            args[i + 1] = ajxmlFile.get(i);
            i++;
            t.next();
        }
        try {
            AJCompiler.main(args);
            StringBuilder sb = AJCompiler.getInstance().getOutputJava();
            if (sb != null) {
                editorJava.setText(sb.toString());
                // System.out.println("compile "+sb.toString());
            }

        } catch (Exception ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }

    }//GEN-LAST:event_bTranslateActionPerformed
/** This method is called when the 'Save' item in the File menu is clicked.
 * It saves the contents of the editor pane to javaFile
 * @param evt
 */
    private void miSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miSaveActionPerformed


        if (editorJava.getText().trim().length() == 0) {
            //JOptionPane.showMessageDialog(this, "Nothing to save!", "FOI", JOptionPane.ERROR_MESSAGE);
            this.setCompileComments("\nNothing to Save");
            return;
        }
        if ((outputJavaFile == null) || (outputJavaFile.length() == 0)) {
            if ((javaFile != null) && (javaFile.length() > 0)) {
                setOutputJavaFile(javaFile);
            }


        }

        if ((outputJavaFile != null) && (outputJavaFile.length() > 0)) {
            try {

                FileOutputStream fo = new FileOutputStream((projectFolder != null ? (projectFolder + "\\src\\") : "") + outputJavaFile);

                PrintWriter out = new PrintWriter(fo);
                //System.out.print(editorJava.getText());
                out.print(editorJava.getText());
                out.flush();
                out.close();
                

                // JOptionPane.showMessageDialog(this, "File saved!", "FOI", JOptionPane.INFORMATION_MESSAGE);
                this.setCompileComments("\nFile Saved");
            } catch (FileNotFoundException fileNotFoundException) {
                this.setCompileComments("Save Error");
            }

        } else {
            miSaveAsActionPerformed(evt);
        }


    }//GEN-LAST:event_miSaveActionPerformed

 /** This method is called when the 'Save' item in the File menu is clicked.
 * It saves the contents of the editor pane to a file selected using a FileChooser.
 * @param evt
 */

    private void miSaveAsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miSaveAsActionPerformed
        // TODO add your handling code here:

        if (JFileChooser.APPROVE_OPTION == getFchos().showSaveDialog(this)) {
            String sf = fchos.getSelectedFile().getAbsolutePath();
            if (!sf.endsWith(".java")) {
                sf += ".java";
            }
            //System.out.println(sf);

            setOutputJavaFile(sf.substring(sf.lastIndexOf("\\") + 1, sf.length()));
            projectFolder = sf.substring(0, sf.lastIndexOf("\\"));

            miSaveActionPerformed(evt);
        }
    }//GEN-LAST:event_miSaveAsActionPerformed
/** This method is called when the 'Compile' button is clicked.
 * It calls the compiler class to compile the source files.
 * The results of compilation are displayed in the compileComments TextPane.
 * It also makes sure that the files are saved before compilation.
 * @param evt
 */
    private void bJavaCompileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bJavaCompileActionPerformed
        // TODO add your handling code here:
        if (projectFolder == null) {
            miSaveAsActionPerformed(evt);
        } else {
            miSaveActionPerformed(evt);
        }
        Compiler jc = new Compiler();
        jc.setMi(this);
        try {

            jc.generateByteCode((projectFolder != null ? (projectFolder + "\\src\\") : "") + outputJavaFile, projectFolder, ".");
            //JOptionPane.showMessageDialog(this, "Class file created!");
            this.setCompileComments("\nClass file Created");
        } catch (Exception ex) {
            //JOptionPane.showMessageDialog(this, ex.getMessage());
            this.setCompileComments("\n"+ ex.getMessage());
        }
    }//GEN-LAST:event_bJavaCompileActionPerformed
/** This method is called when the 'Run' button is pressed.
 * It calls the getRunTime method of the RunTime class to execute the current java file.
 * It also makes sure that the saving and compilation are done before the file is run.
 * @param evt
 */
    private void bRunActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bRunActionPerformed
        // TODO add your handling code here:
        bJavaCompileActionPerformed(evt);
        String fileName;
        fileName = this.outputJavaFile.substring(0, outputJavaFile.indexOf("."));

        String command = "java -cp " + projectFolder +" " + fileName;
        this.setCompileComments("\nRunning project");
        this.setCompileComments("\n"+command);

        Process p = null;
        try {
            p = Runtime.getRuntime().exec(command);

            BufferedReader in = new BufferedReader(
                    new InputStreamReader(p.getInputStream()));
            String line = null;
            StringBuilder sb = new StringBuilder();
            while ((line = in.readLine()) != null) {
                sb.append(line);



            }
            setCompileComments("");
            setCompileComments(sb.toString());

        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);


    }//GEN-LAST:event_bRunActionPerformed
    }
    private void jMenuItem3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem3ActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_jMenuItem3ActionPerformed
/** This method is called when the 'CreateAspectClass' item in the popup menu
 * pmAspectContext is selected.
 * It creates a new Java file from the selected Aspects and
 * adds it to the myaspects package.
 * @param evt
 */
    private void miCreateAspectClassActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miCreateAspectClassActionPerformed
        // TODO add your handling code here:
        AspectConfiguration ac = (AspectConfiguration) lstAspects.getSelectedValue();
        Map<String, AspectMethod> methods = new HashMap<String, AspectMethod>();
        methods = ac.getMethods();


        String fileName = ac.getName() + ".java";

        StringBuilder sb = new StringBuilder();
        sb.append("package myaspects");
        sb = Utils.addNewline(sb);
        sb = Utils.addNewline(sb);
        sb.append("public class " + ac.getName() + "  {");
        sb = Utils.addNewline(sb);
        Properties param = ac.getParams();
        Enumeration nm = param.keys();
        while(nm.hasMoreElements()) {
            String name = nm.toString();
            String value = param.getProperty(name);
            sb.append("\t"+name+" = "+value+";");
            sb = Utils.addNewline(sb);
        }

        for (AspectMethod am : methods.values()) {
            sb = Utils.addTab(sb);
            sb.append(am.getMethodBody());
            sb = Utils.addNewline(sb);
            sb = Utils.addNewline(sb);
        }
        sb.append("}");
        FileOutputStream fo = null;
        try {

            String fname = new java.io.File(".").getAbsolutePath() + "\\src\\myaspects\\" + fileName;
            fo = new FileOutputStream(fname);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
        PrintWriter out = new PrintWriter(fo);
        out.print(sb.toString());
        out.close();




    }//GEN-LAST:event_miCreateAspectClassActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        // TODO add your handling code here:
        Map<String, String> mp = new HashMap();
        mp.put("EID", "495");
        DB db = new DB();
        db.connect((AspectConfiguration) lstAspects.getSelectedValue());
        db.insert("ABC", mp);

    }//GEN-LAST:event_jButton1ActionPerformed
/**This method is clicked when the projectTree is clicked.
 * If the 'src' node is selected, then a popupmenu showing the
 * menuitem 'New' is shown.
 * If a .java file is selected, then it calls openJava method
 * If a .ajxml file is selected, then it calls openConfigFile method.
 * @param evt
 */
    private void projectTreeMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_projectTreeMouseClicked
        // TODO add your handling code here:
        if ((java.awt.event.MouseEvent.BUTTON3 == evt.getButton()) && !projectTree.isSelectionEmpty()) {
            String sel = projectTree.getSelectionPath().toString();
            sel = sel.substring(sel.lastIndexOf(",") + 2, sel.lastIndexOf("]"));

            if (sel.equals("src")) {

                miNewFile.setText("New");

                pmSrcPop.show(projectTree, evt.getX(), evt.getY());
            } else if (sel.equals("build")) {
            } else if (sel.equals("lib")) {
            } else if (sel.equals("inc")) {
            } else 
            {
               
                File f = new File(projectFolder + "\\src\\" + sel);
                String ext = sel.substring(sel.lastIndexOf("."));
                if (ext.equals(".java")) {
                    try {
                        openJava(f);
                    } catch (FileNotFoundException ex) {
                        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (IOException ex) {
                        Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                    }
                } else if (ext.equals(".ajxml")) {

                    openConfigFile(f);

                }
            }

        }





    }//GEN-LAST:event_projectTreeMouseClicked
/**
 * This method is called when the 'New File' item in the pmSrcPop popup menu is selected
 * It opens a FileChooser to select either a java file or an ajxml file.
 * The selected file is passed to the MakeFile class to be added to the projectTree.
 * @param evt
 */
    private void miNewFileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miNewFileActionPerformed
        // TODO add your handling code here:
        if (JFileChooser.APPROVE_OPTION == getFchoo().showOpenDialog(this)) {
            File f = new File(getFchoo().getSelectedFile().getAbsolutePath());
            if (f.getAbsolutePath().lastIndexOf(".") == -1) {
                f = new File(f.getAbsolutePath() + ".java");
                try {
                    f.createNewFile();
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            setJavaFile(f.getAbsolutePath());
            List<String> ls = new ArrayList();
            ls.add(f.getAbsolutePath().substring(f.getAbsolutePath().lastIndexOf("\\") + 1));
            MakeFile.setSrcFile(ls);
            MakeFile.addNodes("src");
            if (f.getName().toLowerCase().endsWith(".ajxml")) {
                openConfigFile(f);
            } else if (f.getName().toLowerCase().endsWith(".java")) {
                try {
                    openJava(f);
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }//GEN-LAST:event_miNewFileActionPerformed
/**
 * This method is called when the 'New Project' item int the FileMenu is selected.
 * it opens a FileChooser to select a new project directory.
 * It calls the newProject and newMake methods of the MakeFile class to
 * create a new project directory and to display the directory in projectTree respectively.
 * It also sets the projectDirectory to the selected directory.
 * @param evt
 */
    private void miNewProjectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_miNewProjectActionPerformed
        //open folder with directories
        JFileChooser chooser = new JFileChooser();

        chooser.setDialogTitle("Project Directory");
        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        //
        // disable the "All files" option.
        //
        chooser.setAcceptAllFileFilterUsed(false);
        if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {




            try {
                MakeFile.newProject(chooser.getSelectedFile().getAbsolutePath());
                MakeFile.newMake(chooser.getSelectedFile().getAbsolutePath());
                projectFolder = chooser.getSelectedFile().getAbsolutePath();

            } catch (IOException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);

            }
        }



    }//GEN-LAST:event_miNewProjectActionPerformed

    private void bRunProjectActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bRunProjectActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_bRunProjectActionPerformed

    /**
     * @param args the command line arguments
     * Loads the main frame.
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new Main().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton bAspect;
    private javax.swing.JButton bJavaCompile;
    private javax.swing.JButton bRun;
    private javax.swing.JButton bRunProject;
    private javax.swing.JButton bTranslate;
    private javax.swing.JTextPane compileComments;
    private javax.swing.JEditorPane editorJava;
    private javax.swing.JButton jButton1;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JMenuItem jMenuItem3;
    private javax.swing.JMenuItem jMenuItem4;
    private javax.swing.JMenuItem jMenuItem5;
    private javax.swing.JMenuItem jMenuItem6;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JToolBar jToolBar1;
    private javax.swing.JList lstAspects;
    private javax.swing.JMenu mEdit;
    private javax.swing.JMenu mFile;
    private javax.swing.JMenuItem miCreateAspectClass;
    private javax.swing.JMenuItem miEditAspect;
    private javax.swing.JMenuItem miInject;
    private javax.swing.JMenuItem miNewFile;
    private javax.swing.JMenuItem miNewProject;
    private javax.swing.JMenuItem miOpen;
    private javax.swing.JMenuItem miSave;
    private javax.swing.JMenuItem miSaveAs;
    private javax.swing.JPopupMenu pmAspectContext;
    private javax.swing.JPopupMenu pmSrcPop;
    private javax.swing.JTree projectTree;
    private javax.swing.JScrollPane treePane;
    // End of variables declaration//GEN-END:variables

    /**
     * This method is used to select .ajava, .java and .ajxml files using FileChooser.
     * @return the fchoo
     */
    public JFileChooser getFchoo() {

        if (fchoo == null) {
            fchoo = new JFileChooser();
            fchoo.setFileFilter(new FileFilter() {

                @Override
                public boolean accept(File f) {

                    if (f.isDirectory()) {
                        return true;
                    }
                    if (f.getName().toLowerCase().endsWith(".java")) {
                        return true;
                    }
                    if (f.getName().toLowerCase().endsWith(".ajava")) {
                        return true;
                    }
                    if (f.getName().toLowerCase().endsWith(".ajxml")) {
                        return true;
                    }
                    return false;
                }

                @Override
                public String getDescription() {
                    return "Java, JAspect files (*.java, *.ajava, *.ajxml)";
                }
            });
        }
        if (projectFolder != null) {

            fchoo.setCurrentDirectory(new File(projectFolder + "\\src"));
        }
        return fchoo;
    }
/**This method opens the .ajxml configuration file.
 * It initializes an instance of the ConfigurationBuilder class from the configuration file
 * and adds it to the list of Aspects.
 * @param f the .ajxml configuration file
 */
    private void openConfigFile(File f) 
    {
        try {

            ConfigurationBuilder cb = new ConfigurationBuilder();

            cb.setFileName(f.getAbsolutePath());
            cb.buildConfigurations(f.getAbsolutePath());
            configs.put(f.getAbsolutePath(), cb);
            this.ajxmlFile.add(f.getAbsolutePath());


            listAspects();


        } catch (Exception ex) {
            //JOptionPane.showMessageDialog(this, ex.getMessage(), "ERROR!", JOptionPane.ERROR_MESSAGE);
            this.setCompileComments("\n"+ex.getMessage());
        }
    }
/**This method is used to list the active Aspects in the list 'lstAspects'
 *
 */
    private void listAspects() {

        // modAspectsList.clear();

        for (ConfigurationBuilder cb : configs.values()) {
            for (AspectConfiguration ac : cb.getAspects().values()) {

                addToAspectList(ac);
                
            }
        }
    }
/**This method is used to add an instance of AspectConfiguration to the list lstAspects
 * @param a the AspectConfiguration instance
 */
    public void addToAspectList(AspectConfiguration a) {

        Enumeration t = modAspectsList.elements();
        int index = 0;
        while (t.hasMoreElements()) {
            if (t.nextElement().toString().equals(a.getName())) {

                modAspectsList.removeElementAt(index);
                break;

            }
            index++;

        }

        modAspectsList.add(index, a);

    }

    /**
     * @return the editorJava
     */
    public javax.swing.JEditorPane getEditorJava() {
        return editorJava;
    }

    /**
     * @return the ajxmlFile
     */
    public List<String> getAjxmlFile() {
        return ajxmlFile;
    }

    /**
     * @param ajxmlFile the ajxmlFile to set
     */
    public void setAjxmlFile(String ajxmlFile) {
        this.ajxmlFile.add(projectFolder + "\\" + ajxmlFile);
    }
/**This method sets the string to the editorpane editorJava.
 * @param toString
 */
    public void setTextFieldTo(String toString) {
        editorJava.setText(toString);
    }

    /**
     * This method is used to select .java files using FileChooser
     * @return the fchos
     */
    public JFileChooser getFchos() {
        if (fchos == null) {
            fchos = new JFileChooser();
            fchos.setFileFilter(new FileFilter() {

                @Override
                public boolean accept(File f) {
                    if (f.isDirectory()) {
                        return true;
                    }
                    if (f.getName().toLowerCase().endsWith(".java")) {
                        return true;
                    }
                    return false;
                }

                @Override
                public String getDescription() {
                    return "Java files (*.java)";
                }
            });

        }
        if (projectFolder != null) {
            fchos.setCurrentDirectory(new File(projectFolder));
        }
        return fchos;
    }

    /**
     * @return the outputJavaFile
     */
    public String getOutputJavaFile() {
        return outputJavaFile;
    }

    /**
     * @param outputJavaFile the outputJavaFile to set
     */
    public void setOutputJavaFile(String outputJavaFile) {
        this.outputJavaFile = outputJavaFile;
    }
/**This method sets the results of compilation passed as string to the textpane 'compileComments'
 * @param s  the compilation warnings
 */
    public void setCompileComments(String s) {
        if (s.equals("")) {
            compileComments.setText("");
        } else {
            StringBuilder sb = new StringBuilder();
            sb.append(compileComments.getText());
            sb.append(s);
            compileComments.setText(sb.toString());
        }
    }
}
